package com.bzy.blp.upms.service.impl;

import com.bzy.blp.mapper.TSystemUserInfoDatMapper;
import com.bzy.blp.model.TSystemUserInfoDat;
import com.bzy.blp.model.TSystemUserInfoDatCriteria;
import com.bzy.blp.service.ISystemUserManagerService;
import com.bzy.blp.upms.mapper.AccountMapper;
import com.bzy.blp.upms.service.CommonService;
import com.bzy.blp.upms.service.UserService;
import com.bzy.blp.upms.utils.AppConstants;
import com.bzy.blp.upms.vo.AccountDetailVO;
import com.bzy.blp.upms.vo.AccountVO;
import com.bzy.blp.upms.vo.AppRoleDto;
import com.bzy.blp.upms.vo.request.AccountRequest;
import com.bzy.common.exception.LogicException;
import com.bzy.shiro.util.PasswordUtil;
import com.bzy.shiro.util.SessionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.Account;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

import javax.annotation.Resource;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    AccountMapper accountMapper;

    @Autowired
    TSystemUserInfoDatMapper systemUserInfoDatMapper;

	@Resource
	CommonService commonService;

//	@Resource
//	private IAppKeyService appKeyService;
	@Resource
	ISystemUserManagerService systemUserManagerService;

	@Override
	public void deleteUser(Long userId) throws Exception {

	}

	@Override
	public TSystemUserInfoDat findOne(Long userId) throws Exception {
		return null;
	}

	@Override
	public List<TSystemUserInfoDat> findAll() throws Exception {
		return null;
	}

	@Override
	public void changePassword(Long userId, String newPassword) throws Exception {

	}

	@Override
	public TSystemUserInfoDat findByUsername(String username) throws Exception {
		TSystemUserInfoDat data = new TSystemUserInfoDat();
		data.setUserName(username);
		data.setIsDelete(false);
//		LoggerUtil.info("...... this is upmsUserData : " + JSONUtils.converterToString(data));
//		TSystemUserInfoDat entity = tblUpmsUserInfoDatService.getByField(data);
//		LoggerUtil.info("-------- result upms entity : " + JSONUtils.converterToString(entity));
		TSystemUserInfoDat entity = systemUserManagerService.queryUserByUserName(username);
		return entity;
	}

	@Override
	public Long findUseridByUsername(String username) throws Exception {
		return findByUsername(username).getUserId();
	}

	@Override
	public Set<String> findPermissions(Long userId, Long appId) throws Exception {
		return null;
	}


	@Override
	public void userLogin(String username, String password, boolean rememberMe, String host) throws Exception {
		AuthenticationToken token = new UsernamePasswordToken(username, password, rememberMe, host);
		SecurityUtils.getSubject().login(token);
		loginHandler();
	}

	@Override
	public void loginHandler() throws Exception {
		String appKey = (String) SessionUtil.getOauthAppkey();
		/*if (StringUtil.isBlank(appKey)) {
			appKey = appKeyService.getAppKey();
			SessionUtil.setOauthAppkey(appKey);
		}*/

        // 登录名
		String userName = (String) SessionUtil.getPrincipal();
		Long userId = commonService.findUserId(userName);
		// appid 应用id暂时不用
		Long appId = commonService.findAppId(appKey);
		Set<String> roles = commonService.findRoles(userId, appId);
		Set<String> permissions = commonService.findPermissions(userId, appId);
		SessionUtil.setUserRoles(roles);
		SessionUtil.setUserPermissions(permissions);
		SessionUtil.setAccountId(userId.toString());
        updateLoginDate(userId);
	}

	// 记录登录时间
	private void updateLoginDate(Long userId) throws Exception {
	    TSystemUserInfoDat userInfo = new TSystemUserInfoDat();
	    userInfo.setUserId(userId);
	    userInfo.setLastLoginTime(new Date());
        systemUserInfoDatMapper.updateByPrimaryKeySelective(userInfo);
    }


	@Override
	public PageInfo<AccountVO> getAccountList(String userName, int pageNo, int pageSize) throws Exception {
        PageHelper.startPage(pageNo, pageSize);
        List<AccountVO> accountVOS = accountMapper.queryAccountList(userName);
        PageInfo<AccountVO> pageInfo = new PageInfo<>(accountVOS);
        List<AccountVO> list = pageInfo.getList();

        // 遍历
        list.forEach(account -> {
            Long userId = account.getUserId();
            List<AppRoleDto> appRoleDtos = accountMapper.queryAccountAppRole(userId);
            appRoleDtos.forEach(appRole -> {
                setAccountRoleWithAppKey(account, appRole);
            });
        });

        return pageInfo;
	}

    @Override
    public AccountDetailVO getAccountDetail(Long userId) throws Exception {
        TSystemUserInfoDatCriteria criteria = new TSystemUserInfoDatCriteria();
        criteria.createCriteria()
                .andUserIdEqualTo(userId)
                .andIsDeleteEqualTo(Boolean.FALSE);
        List<TSystemUserInfoDat> systemUserInfoDats = systemUserInfoDatMapper.selectByExample(criteria);
        if (systemUserInfoDats != null && systemUserInfoDats.size() > 0) {
            TSystemUserInfoDat userInfo = systemUserInfoDats.get(0);

            AccountDetailVO account = resetSystemUser(userInfo);
            List<AppRoleDto> appRoleDtos = accountMapper.queryAccountAppRole(userId);
            appRoleDtos.forEach(role -> {
                setAccountRoleWithAppKey(account, role);
            });

            return account;
        }

        return null;
    }

    @Override
    public void updateAccountInfo(AccountRequest accountRequest) throws Exception {
	    if (accountRequest == null
                || (accountRequest != null && accountRequest.getUserId() == null)) {
	        throw new LogicException("修改信息不能为空");
        }
        TSystemUserInfoDat record = new TSystemUserInfoDat();
        record.setUserId(accountRequest.getUserId());
        record.setRealName(accountRequest.getRealName());
        record.setMobile(accountRequest.getMobile());
        record.setEmail(accountRequest.getEmail());
        record.setAccountStatus(accountRequest.getAccountStatus());
        record.setUpdateTime(new Date());
        record.setUpdatePeople(accountRequest.getOperatePeople());
        systemUserInfoDatMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public void addAccountInfo(AccountRequest accountRequest) throws Exception {
        if (accountRequest == null
                || (accountRequest != null && accountRequest.getUserId() == null)) {
            throw new LogicException("添加信息不能为空");
        }
        TSystemUserInfoDat record = new TSystemUserInfoDat();
        record.setUserName(accountRequest.getUserName());
        String salt = PasswordUtil.generateSalt();
        record.setSalt(salt);
        record.setPassword(PasswordUtil.encryptPassword(record.getUserName(),record.getPassword(),salt));
        record.setRealName(accountRequest.getRealName());
        record.setMobile(accountRequest.getMobile());
        record.setEmail(accountRequest.getEmail());
        record.setAccountStatus(accountRequest.getAccountStatus());
        record.setCreateTime(new Date());
        record.setCreatePeople(accountRequest.getOperatePeople());
        systemUserInfoDatMapper.insertSelective(record);
    }

    @Override
    public void updateUserPassword(Long userId, String oldPassword, String newPassword, String uptType) throws Exception {
        if (userId == null)
            throw new LogicException("用户id不能为空");
        if (StringUtils.isBlank(uptType))
            throw new LogicException("修改密码类型不能为空");

        TSystemUserInfoDat tSystemUserInfoDat = systemUserInfoDatMapper.selectByPrimaryKey(userId);
        TSystemUserInfoDat record = new TSystemUserInfoDat();
        record.setUpdatePeople(tSystemUserInfoDat.getUserName());
        record.setUpdateTime(new Date());
        String salt = PasswordUtil.generateSalt();
        record.setSalt(salt);

        // 重置当前用户密码时，判断旧密码是否正确
        if (uptType.equals("1")) {
           String calcuPwd = PasswordUtil.encryptPassword(tSystemUserInfoDat.getUserName(), oldPassword, tSystemUserInfoDat.getSalt());
           if (!calcuPwd.equals(tSystemUserInfoDat.getPassword())){
               throw new LogicException("旧密码不正确");
           }
        }
        String encryptPwd = PasswordUtil.encryptPassword(tSystemUserInfoDat.getUserName(), newPassword, salt);
        record.setPassword(encryptPwd);
        systemUserInfoDatMapper.updateByPrimaryKeySelective(record);
	}


    private AccountDetailVO resetSystemUser(TSystemUserInfoDat user) throws InvocationTargetException, IllegalAccessException {
        AccountDetailVO accountDetailVO = new AccountDetailVO();
        if (user != null) {
            accountDetailVO.setUserId(user.getUserId());
            accountDetailVO.setUserName(user.getUserName());
            accountDetailVO.setRealName(user.getRealName());
            accountDetailVO.setNickName(user.getNickName());
            accountDetailVO.setHeadPortrait(user.getHeadPortrait());
            accountDetailVO.setMobile(user.getMobile());
            accountDetailVO.setEmail(user.getEmail());
            accountDetailVO.setDescription(user.getDescription());
            accountDetailVO.setCreateTime(user.getCreateTime());
            accountDetailVO.setUpdateTime(user.getUpdateTime());
            accountDetailVO.setLastLoginTime(user.getLastLoginTime());
            accountDetailVO.setCreatePeople(user.getCreatePeople());
            accountDetailVO.setUpdatePeople(user.getUpdatePeople());
            accountDetailVO.setAccountStatus(user.getAccountStatus());
        }
        return accountDetailVO;
    }

    private void setAccountRoleWithAppKey(Object bean, AppRoleDto appRole) {
        if (bean == null) return;

        if (bean instanceof AccountVO) {
            AccountVO account = (AccountVO) bean;
            // app客户端权限
            if (appRole.getAppKey().equals(AppConstants.APP_KEY)) {
                account.setAppRoleName(appRole.getRoleNameZh());
            }
            // pc后台管理权限
            if (appRole.getAppKey().equals(AppConstants.PC_KEY)) {
                account.setPcRoleName(appRole.getRoleNameZh());
            }
        } else if (bean instanceof  AccountDetailVO) {
            AccountDetailVO account = (AccountDetailVO) bean;
            // app客户端权限
            if (appRole.getAppKey().equals(AppConstants.APP_KEY)) {
                account.setAppRoleName(appRole.getRoleNameZh());
            }
            // pc后台管理权限
            if (appRole.getAppKey().equals(AppConstants.PC_KEY)) {
                account.setPcRoleName(appRole.getRoleNameZh());
            }
        }
    }



}
